<?php

namespace App\Livewire;

use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Table;
use FilesystemIterator;
use Livewire\Component;
use App\Models\Project;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Actions\Action;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use ZipArchive;
use Filament\Infolists\Infolist;
use Filament\Infolists\Components\TextEntry;
use Filament\Support\Enums\Alignment;

class MyProjects extends Component implements HasForms, HasTable
{
    use InteractsWithTable, InteractsWithForms;
    public function render()
    {
        return view('livewire.my-projects');
    }

    public function table(Table $table): Table
    {
        return $table
            ->query(Project::query()->where('user_id', auth()->id()))
            ->columns([
                TextColumn::make('id')->label('ID'),
                TextColumn::make('title')->label('名称'),
                TextColumn::make('project_type')->label('项目类型'),
                TextColumn::make('created_at')->label('创建时间'),
            ])
            ->filters([
                //
            ])
            ->actions([
                Action::make('downloadProject')
                    ->label('下载')
                    ->action(function ($record) {
                        $project_directory = storage_path('app/projects/' . $record->id);
                        $zipFilePath = storage_path('app/projects/' . $record->id . '.zip');
                        $this->zipProjectContents($project_directory, $zipFilePath);
                    })->icon('heroicon-o-folder-arrow-down'),
                Action::make('viewDetails')
                   ->label('查看详情')
                   ->icon('heroicon-o-document-magnifying-glass')
                   ->modalHeading('项目详情')
                    ->infolist(function (Infolist $infolist, $record) {
                        return $infolist
                            ->record($record)
                            ->schema([
                                TextEntry::make('title')->label('Full title'),
                                TextEntry::make('project_type')->label('Project type'),
                                TextEntry::make('description')->label('Description'),
                                TextEntry::make('created_at')->label('Created at'),
                            ]);
                    })->modalFooterActionsAlignment(Alignment::Right),

            ])
            ->bulkActions([
                //
            ]);
    }

    /**
     * @throws \Exception
     */
    public function zipProjectContents($sourceDir, $zipFilePath)
    {
        if (!extension_loaded('zip')) {
            throw new \Exception('Zip extension is not loaded.');
        }

        $zip = new ZipArchive();

        if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
            throw new \Exception("Could not create zip file at $zipFilePath");
        }

        $sourceDir = realpath($sourceDir);

        if (!$sourceDir) {
            throw new \Exception("Source directory does not exist.");
        }

        $files = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($sourceDir, FilesystemIterator::SKIP_DOTS),
            RecursiveIteratorIterator::SELF_FIRST
        );

        foreach ($files as $file) {
            $filePath = $file->getRealPath();
            $relativePath = substr($filePath, strlen($sourceDir) + 1);

            if ($file->isDir()) {
                $zip->addEmptyDir($relativePath);
            } else {
                $zip->addFile($filePath, $relativePath);
            }
        }

        $zip->close();
    }

}
